﻿using System.Collections;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;

namespace IPScanner
{
    internal class ScanHelper
    {
        public event EventHandler<ScanReportArgs> ScanReport;
        public event EventHandler<ScanCompletedArgs> ScanCompleted;

        public async void EnumComputers(string ipStart)
        {
            EnumComputers(new IPRangeItem
            {
                StartAddress = int.Parse(ipStart.Substring(ipStart.LastIndexOf('.'))) + 1,
                EndAddress = 255,
                IpPrefix = ipStart.Substring(0, ipStart.LastIndexOf('.') + 1)
            });
        }

        public async void EnumComputers(IPRangeItem iPRangeItem)
        {
            var taskCount = iPRangeItem.EndAddress - iPRangeItem.StartAddress;
            var ret = System.Threading.Tasks.Parallel.For(iPRangeItem.StartAddress, iPRangeItem.EndAddress + 1, async i =>
            {
                try
                {
                    Ping myPing;
                    myPing = new Ping();
                    string pingIP = iPRangeItem.IpPrefix + i.ToString();

                    var ret = await myPing.SendPingAsync(IPAddress.Parse(pingIP), 5000);

                    if (ret.Status == IPStatus.Success)
                    {
                        var item = new HostItem
                        {
                            Address = ret.Address.ToString(),
                            IsOnline = PingStatus.Online,
                            BufferLength = ret.Buffer?.Length ?? 0,
                            ReplayTime = ret.RoundtripTime
                        };
                        //try
                        //{
                        //    var host = Dns.GetHostEntry(item.Address);
                        //    item.Name = host.HostName;
                        //}
                        //catch
                        //{
                        //}
                        ScanReport?.Invoke(this, new ScanReportArgs(item));
                    }
                    else
                    {
                        ScanReport?.Invoke(this, new ScanReportArgs(pingIP));
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    System.Threading.Interlocked.Add(ref taskCount, -1);
                }
            });

            await Task.Run(() =>
            {
                while (taskCount > 0) Task.Delay(100);
                ScanCompleted?.Invoke(this, new ScanCompletedArgs { });
            });
        }
    }
}
